package com.twang.stock.controller.common;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.twang.stock.common.http.HtmlTools;
import com.twang.stock.dto.BaseRequest;
import com.twang.stock.dto.EmailMessage;
import com.twang.stock.dto.TenXunStock;
import com.twang.stock.entity.CompanyCodeInfo;
import com.twang.stock.entity.CompanyStock;
import com.twang.stock.entity.CompanyStockMinutes;
import com.twang.stock.entity.User;
import com.twang.stock.feign.ZuoTiStatusFeignService;
import com.twang.stock.mapper.CompanyStockMapper;
import com.twang.stock.mapper.CompanyStockMinutesMapper;
import com.twang.stock.mapper.UserMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.rocketMq.RocketMQProducer;
import com.twang.stock.service.CompanyStockMinutesService;
import com.twang.stock.service.CompanyStockService;
import com.twang.stock.service.IndexService;
import com.twang.stock.service.ZhangTingBanService;
import com.twang.stock.service.impl.CompanyStockServiceImpl;
import com.twang.stock.email.SendmailService;

import com.twang.stock.task.MinutesStockFixTask;
import com.twang.stock.task.old.BaseTask;
import com.twang.stock.utils.R;
import com.twang.stock.utils.date.DateUtils;
import com.twang.stock.utils.date.HolidayCopy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/zuot")
@Slf4j
public class DuanXianZuoTiController {

    @Autowired
    private ZhangTingBanService zhangTingBanService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BaseTask baseTask;

    @Autowired
    private IndexService indexService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private CompanyStockMinutesMapper companyStockMinutesMapper;

    @Autowired
    private CompanyStockMinutesService companyStockMinutesService;

    @Resource
    private SendmailService sendmailService;

    @Autowired
    private MinutesStockFixTask minutesStockFixTask;


    @Autowired
    private RocketMQProducer rocketMQProducer;

    @Autowired
    private CompanyStockService companyStockService;

    @Resource
    private CompanyStockMapper companyStockMapper;


    @Autowired
    private ZuoTiStatusFeignService zuoTiStatusFeignService;

    // 注入HttpSession
    @Autowired
    private HttpSession httpSession;

    public static String TOKEN="accessToken";

    public static String EMAIL="EMAIL_";

    private static String COMPANY_STOCK_CODE_LIST_ZUO_T = "COMPANY_STOCK_CODE_LIST_ZUO_T";



    @RequestMapping(value = "/ajaxRequestCompanyInfo")
    public void ajaxRequestCompanyInfo(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String keyword = request.getParameter("keyword");
        List<Company> result = Lists.newArrayList();
        if (StringUtils.isNotBlank(keyword)) {
            List<CompanyCodeInfo> list = minutesStockFixTask.getCompanyCodeInfos();
            list.forEach(item -> {
                if((null!=item.getShortName()&&item.getShortName().contains(keyword.toUpperCase()))
                        ||(null!=item.getCompanyShort()&&item.getCompanyShort().contains(keyword.toUpperCase()))
                        ||(null!=item.getCompanyCode()&&item.getCompanyCode().contains(keyword.toUpperCase()))){
                    result.add(new Company(item.getId().intValue(), item.getShortName()));
                }
            });
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        //输出到客户端
        out.println(JSONObject.toJSONString(result));
        out.flush();
        out.close();
    }
    @GetMapping(value = "/stockKey")
    public ModelAndView stockKey(String key) throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        //
        Object token = httpSession.getAttribute(TOKEN);
        log.info(">>>>>>>>>>>> token={} key={} ",token,key);
        if (null==token) {
            token = COMPANY_STOCK_CODE_LIST_ZUO_T + "_" + HolidayCopy.getHHmmss();
            log.info(">>>>>>>>>>>> set token={} key={} ",token,key);
            httpSession.setAttribute(TOKEN, token);
            redisUtil.set(token.toString(), key);
        }
        //
        if (null == redisUtil.get(token.toString()) || redisUtil.get(token.toString()).toString().length() < 5) {
            if(StringUtils.isNotEmpty(key)){
                log.info(">>>>>>>>>>>> key is not empty,key={}  token={}",key, token);
                redisUtil.set(token.toString(), key);
                stockKey(key);
            }else{
                modelAndView.addObject("zuotList", Lists.newArrayList());
            }
        } else {
            log.info(">>>>>>>>>>>> key={} ",key);
            String tempKey = key;
            key = redisUtil.get(token.toString()).toString().replace(",,", ",");
            //add key
            if (StringUtils.isNotBlank(tempKey) && !key.contains(tempKey)) {
                key = new StringBuffer(key).append(",").append(tempKey).toString();
                redisUtil.set(token.toString(), key);
            }
            String[] keys = key.replace(",,", ",").split(",");
            StringBuffer buffer = new StringBuffer("");
            for (String str : keys) {
                buffer.append("s_").append(str).append(",");
            }
            key=buffer.toString().replace("s_s_","s_").replace(",s_,",",");
            List<TenXunStock> tenXunStocks = HtmlTools.httpGet(key);
            log.info(">>>>>>>>>>>> extractedstockInfo start EMAIL + token={} ",EMAIL + token);
            extractedstockInfo(tenXunStocks, EMAIL + token);
            log.info(">>>>>>>>>>>> extractedstockInfo end tenXunStocks={} ",JSONObject.toJSONString(tenXunStocks));

            //
            indexService.isReflash(modelAndView);
            Object email = redisUtil.get(EMAIL + token);
            if (null != email) {
                log.info(">>>>>>>>>>>> 拉去自选 拉去自选 end email={} ",email);
                //拉取自选数据
                拉去自选(token, tenXunStocks, email);
                //更新自选数据
                modelAndView.addObject("email", email);
            }
            modelAndView.addObject("zuotList", tenXunStocks);
        }
        modelAndView.setViewName("duanXianZuoT");
        return modelAndView;
    }

    private void 拉去自选(Object token, List<TenXunStock> tenXunStocks, Object email) throws Exception {
        User param=new User();
        param.setEmail(email.toString());
        User user= userMapper.selectOne(param);
        List<CompanyStock> companyStocks=companyStockService.selectById(user.getId());
        if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(companyStocks)) {
            tenXunStocks.stream().forEach(item -> {
                List<CompanyStock> companyStockTemp = companyStocks.stream().filter(p -> p.getCompanyCode().equals(item.getStockCode())).collect(Collectors.toList());
                if (!org.apache.commons.collections4.CollectionUtils.isNotEmpty(companyStockTemp)) {
                    redisUtil.del(new StringBuffer(CompanyStockServiceImpl.ZI_XUAN_CHI_KEY).append("_").append(user.getId()).toString());
                    try {
                        companyStockService.addStock(item.getStockCode(), item.getStockName(),user.getId(),item);
                    } catch (Exception e) {
                        log.error(">>>>>>>>>>> stockKey companyStockService addStock error={}", e);
                        throw new RuntimeException(e);
                    }
                }
            });
            List<CompanyStock> list = companyStockService.selectById(user.getId());
            StringBuffer newBufKey = new StringBuffer("");
            for (CompanyStock str : list) {
                newBufKey.append("s_").append(str.getCompanyCode()).append(",");
            }
            String newKey = newBufKey.toString().replace(",,", ",");
            log.info(">>>>>>>>>>>> 拉去自选 拉去自选 end newKey={} ",newKey);
            redisUtil.set(token.toString(), newKey);
        }else{
            //新邮箱添加
            tenXunStocks.stream().forEach(item -> {
                    redisUtil.del(new StringBuffer(CompanyStockServiceImpl.ZI_XUAN_CHI_KEY).append("_").append(user.getId()).toString());
                    try {
                        companyStockService.addStock(item.getStockCode(), item.getStockName(),user.getId(),item);
                    } catch (Exception e) {
                        log.error(">>>>>>>>>>> stockKey companyStockService addStock error={}", e);
                        throw new RuntimeException(e);
                    }
            });
            List<CompanyStock> list = companyStockService.selectById(user.getId());
            StringBuffer newBufKey = new StringBuffer("");
            for (CompanyStock str : list) {
                newBufKey.append("s_").append(str.getCompanyCode()).append(",");
            }
            String newKey = newBufKey.toString().replace(",,", ",");
            log.info(">>>>>>>>>>>> 拉去自选 拉去自选 end newKey={} ",newKey);
            redisUtil.set(token.toString(), newKey);
        }
    }

    /**
     * 添加
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/ajaxRequestAddStockKey")
    public void ajaxRequestAddStockKey(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Object token = httpSession.getAttribute(TOKEN);
        String msg = "";
        String keyWords = request.getParameter("keyWords");
        if (!Objects.isNull(token)) {
            String key = "";
            Object obj = redisUtil.get(token.toString());
            if (null == obj) {
                key = keyWords;
                redisUtil.set(token.toString(), key);
            } else {
                key = obj.toString();
            }
            if (!key.contains(keyWords)) {
                redisUtil.set(token.toString(), key + "," + keyWords);
            }
            msg = "Success";
        } else {
            msg = "Fail";
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        //输出到客户端
        out.println(msg);
        out.flush();
        out.close();
    }

    /**
     * 删除
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/ajaxRequestDelStockKey")
    public void ajaxRequestDelStockKey(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Object token=httpSession.getAttribute(TOKEN);
        String msg="";
        if(!Objects.isNull(token)) {
            //
            String key = redisUtil.get(token.toString()).toString();
            String keyWords = request.getParameter("keyWords");
            key = key.replace(keyWords, "").replace(",,", ",");
            //
            redisUtil.set(token.toString(), key);
            //删除自选
            {
                Object email=redisUtil.get(EMAIL+token.toString());
                if(null!=email){
                    User param=new User();
                    param.setEmail(email.toString());
                    User user= userMapper.selectOne(param);
                    CompanyStock companyStock = new CompanyStock();
                    companyStock.setUserId(user.getId().intValue());
                    companyStock.setCompanyCode(keyWords.replace(",","").replace("s_","").replace("s_s_",""));
                    CompanyStock result=  companyStockMapper.selectOne(companyStock);
                    if(null!=result){
                        log.info(">>>>>>>>>>>> ajaxRequestDelStockKey result delete :{}",JSONObject.toJSONString(result));
                       int num= companyStockMapper.deleteByPrimaryKey(result.getId());
                        log.info(">>>>>>>>>>>> ajaxRequestDelStockKey result delete num={}",num);
                        //key= key.replace(keyWords,"").replace("s_s_","").replace(",,","");
                       //redisUtil.set(token.toString(),key);
                        stockKey(null);
                    }
                }
            }
            msg = "Success";
        }else{
            msg="Fail";
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        //输出到客户端
        out.println(msg);
        out.flush();
        out.close();
    }

    /**
     * 添加邮箱
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/ajaxRequestAddEmail")
    public void ajaxRequestAddEmail(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Object token = httpSession.getAttribute(TOKEN);
        String msg = "";
        String emailKEy = "";
        if (!Objects.isNull(token)) {
            //
            Object obj = redisUtil.get(EMAIL + token.toString());
            if (null != obj) {
                msg = "请勿重复添加";
            } else {
                emailKEy = EMAIL + token;
                String email = request.getParameter("email");
                if (StringUtils.isEmpty(email)) {
                    msg = "Email格式错误";
                } else {
                    //
                    redisUtil.set(emailKEy, email);
                    //
                    User param=new User();
                    param.setEmail(email);
                   List<User> users=userMapper.select(param);
                   if(CollectionUtils.isEmpty(users)){
                       User user=new User();
                       user.setEmail(email);
                       user.setNameDesc("预警添加,time:"+HolidayCopy.getHHmmss());
                       user.setUserName(email);
                       user.setPassword("123456");
                       userMapper.insert(user);
                   }
                    msg = "Success";
                }
            }
        } else {
            msg = "Fail";
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        //输出到客户端
        out.println(msg);
        out.flush();
        out.close();
    }
    /**
     *
     * @param tenXunStocks
     */
    private void extractedstockInfo(List<TenXunStock> tenXunStocks,String emailToken) {
        tenXunStocks.stream().forEach(p -> {
            R result = zuoTiStatusFeignService.queryZuoTiStatus(tenXunStocks.get(0));
            Object object = result.get("data");
            p = JSONObject.parseObject(JSONObject.toJSONString(object), TenXunStock.class);
            // extractedZuoTi(p);
        });
    }

    private void extractedZuoTi(TenXunStock p) {
        if (51 == p.getExchange()) {
            p.setStockCode("sz" + p.getStockCode());
        } else {
            p.setStockCode("sh" + p.getStockCode());
        }
        List<String> dates = companyStockMinutesMapper.queryDates();
        /** 昨天 */
        String date = dates.get(dates.size() - 2);
        BigDecimal yestoDayMaxVol;
        String key_avg_volume=new StringBuffer("key_avg_volume").append("_").append(p.getStockCode()).append("_").append(HolidayCopy.getToday()).toString();
        Object object=redisUtil.get(key_avg_volume);
        if(null==object) {
            yestoDayMaxVol= companyStockMinutesService.getMaxVol(date, p.getStockCode());
            if (p.getStockCode().startsWith("sh688")) {
                yestoDayMaxVol = yestoDayMaxVol.divide(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP);
            }
            redisUtil.set(key_avg_volume, yestoDayMaxVol.toString());
        }else {
            yestoDayMaxVol = new BigDecimal(object.toString());
        }
        if (p.getStockCode().startsWith("sh688")) {
            p.setTradingVolume(p.getTradingVolume().divide(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        }
        //更新分钟量能
        Example example = new Example(CompanyStockMinutes.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("date", HolidayCopy.getRealToday());
        criteria.andEqualTo("companyCode", p.getStockCode());
        example.orderBy("id").desc();
        List<CompanyStockMinutes> list = companyStockMinutesMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            CompanyStockMinutes last = list.get(0);
            BigDecimal newVole = p.getTradingVolume().subtract(last.getTradeVol());
            if (newVole.compareTo(yestoDayMaxVol) > 0) {
                //触发了
                p.setTFlags(1);
            } else {
                p.setTFlags(0);
            }
        }
        p.setTurnover(p.getTradingVolume().divide(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP));
        /** 判断是否需要刷新*/
        if (baseTask.isWorkTradeTime()) {
            p.setIsFlash(1);
        } else {
            p.setIsFlash(0);
        }
    }

    private void sendEmail(String emailToken, TenXunStock p) {
        Object email=redisUtil.get(emailToken);
        if(null!=email) {
            log.info(">>>>>>>>> send email={}",email);
            String messages = new StringBuffer("触发做T时间：").append(DateUtils.getNow()).toString();
            try{
                EmailMessage emailMessage=new EmailMessage();
                emailMessage.setCode(p.getStockCode());
                emailMessage.setName(p.getStockName());
                emailMessage.setEmail(email.toString());
                emailMessage.setMessage(messages);
                //emailMessage.setUserId();
                //String reg="|";
               //String msg=  new StringBuffer(messages).append(reg).append(p.getStockName()).append(reg).append(p.getStockCode()).append(reg).append(email).toString();
                 rocketMQProducer.sendOneWay(JSONObject.toJSONString(emailMessage));
            }catch (Exception e){
                sendmailService.sendMailWithByZuoT(messages, p.getStockName(), p.getStockCode(), email.toString());
            }
        }
    }

    @RequestMapping(value = "/ajaxRequest")
    public void ajaxRequestGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
                doAjaxRequestGetSyn(request,response);
    }


    /**
     * 异步请求-单个
     * @param request
     * @param response
     * @throws IOException
     */
    private void doAjaxRequestGetSyn(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // String code = request.getParameter("code");
        String data = request.getParameter("data");
        Object token = httpSession.getAttribute(TOKEN);
        if (StringUtils.isEmpty(data.replace("\n", ""))) {
            return;
        }
        TenXunStock tenXunStock = HtmlTools.cvoertDTO(data);
        if (tenXunStock.getStockCode().startsWith("688")) {
            tenXunStock.setTradingVolume(tenXunStock.getTradingVolume().divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        List<String> dates = companyStockMinutesMapper.queryDates();
        /** 昨天 */
        if (51 == tenXunStock.getExchange()) {
            tenXunStock.setStockCode("sz" + tenXunStock.getStockCode());
        } else {
            tenXunStock.setStockCode("sh" + tenXunStock.getStockCode());
        }
        int i = 2;
        int j = 0;
        String key = "key_yj_zuo_t_" + HolidayCopy.getRealToday() + "_" + tenXunStock.getStockCode();
        BigDecimal hisDayTradeVol = BigDecimal.ZERO;
        Object hisDayTradeVolCache = redisUtil.get(key);
        if (null == hisDayTradeVolCache) {
            for (String date : dates) {
                date = dates.get(dates.size() - i);
                //排除涨停的数据
                Boolean isTrue = zhangTingBanService.zhangtingDatahis(tenXunStock.getStockCode(), date);
                if (!isTrue) {
                    BigDecimal yestoDayMaxVol = companyStockMinutesService.getMaxVol(date, tenXunStock.getStockCode());
                    hisDayTradeVol = hisDayTradeVol.add(yestoDayMaxVol);
                    j++;
                }
                i++;
                if (j == 4) {
                    break;
                }
            }
            hisDayTradeVol = hisDayTradeVol.divide(new BigDecimal(5)).setScale(0, BigDecimal.ROUND_HALF_UP);
            redisUtil.set(key, hisDayTradeVol.toString());
        } else {
            hisDayTradeVol = new BigDecimal(hisDayTradeVolCache.toString());
        }
        //更新分钟量能
        Example example = new Example(CompanyStockMinutes.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("date", HolidayCopy.getRealToday());
        criteria.andEqualTo("companyCode", tenXunStock.getStockCode());
        example.orderBy("id").desc();
        List<CompanyStockMinutes> list = companyStockMinutesMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            CompanyStockMinutes last = list.get(0);
            BigDecimal newVole = tenXunStock.getTradingVolume().subtract(last.getTradeVol());
            if (newVole.compareTo(hisDayTradeVol) > 0) {
                tenXunStock.setTFlags(1);
                sendEmail(EMAIL + token, tenXunStock);
            } else {
                tenXunStock.setTFlags(0);
            }
            tenXunStock.setYjTime(DateUtils.getNow());
            tenXunStock.setTurnover(tenXunStock.getTradingVolume().divide(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP));
            //
        }
        /** 判断是否需要刷新*/
        if (baseTask.isWorkTradeTime()) {
            tenXunStock.setIsFlash(1);
        } else {
            tenXunStock.setIsFlash(0);
        }
        tenXunStock.setIsFlash(1);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        //输出到客户端
        out.println(JSONObject.toJSONString(tenXunStock));
        out.flush();
        out.close();
    }

    @RequestMapping(value = "/indexNew")
    public ModelAndView indexNew(BaseRequest request) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("pages/index_v5");
        return modelAndView;
    }
    @Data
    static class Company implements Serializable {
        private int id;
        private String name;
        public Company(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }

}
